package com.yqg.protection.controller;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yqg.protection.common.Result;
import com.yqg.protection.common.interceptor.SysLog;
import com.yqg.protection.controller.dto.UserDTO;
import com.yqg.protection.controller.dto.UserPasswordDTO;
import com.yqg.protection.controller.vo.UserClientVO;
import com.yqg.protection.entity.Client;
import com.yqg.protection.entity.Organization;
import com.yqg.protection.entity.RecordOperate;
import com.yqg.protection.entity.User;
import com.yqg.protection.listenern.NoticeWebsocket;
import com.yqg.protection.mapper.UserMapper;
import com.yqg.protection.service.IClientService;
import com.yqg.protection.service.IOrganizationService;
import com.yqg.protection.service.IRecordOperateService;
import com.yqg.protection.service.IUserService;
import com.yqg.protection.utils.Constants;
import com.yqg.protection.utils.IPUtils;
import com.yqg.protection.utils.OrganUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * UserController 前端控制器
 *
 * @author zxf
 * @since 2024-01-01
 */
@Log4j2
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private IUserService userService;

    @Autowired
    private IClientService clientService;

    @Autowired
    OrganUtils organUtils;

    @Autowired
    IPUtils ipUtils;

    @Autowired
    private IOrganizationService organizationService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IRecordOperateService recordOperateService;

    @Resource
    private NoticeWebsocket noticeWebsocket;

    @PostMapping("/login")
    public Result login(HttpServletRequest request, @RequestBody UserDTO userDTO) {
        String username = userDTO.getUsername();
        String password = userDTO.getPassword();
        log.info("username:" + username);
        if (StrUtil.isBlank(username) || StrUtil.isBlank(password)) {
            return Result.error(Constants.String_CODE_400, "参数错误");
        }
        UserDTO dto = userService.login(userDTO);
        RecordOperate recordOperate = new RecordOperate();
        recordOperate.setUserId(userDTO.getId().longValue());
        recordOperate.setIsDelete(0);
        recordOperate.setOperateType("com.yqg.protection.controller.UserController.login()");
        recordOperate.setContent("用户登录");
        recordOperate.setUserIp(ipUtils.getIpAddr(request));
        recordOperate.setCreatedTime(LocalDateTime.now());
        recordOperateService.save(recordOperate);
        return Result.success(dto);
    }

    @GetMapping("/sendMessage")
    public void sendSendMessage() {
        Map<String, Object> map = new HashMap<>();
        map.put("type", "video");
        map.put("msg", "有报警设备，请立刻进行处理");
        noticeWebsocket.sendMessage(map);
    }

    /**
     * 获取用户绑定单位
     * @param userId
     * @return
     */
    @GetMapping("/getClient")
    public Result getClient(@RequestParam Long userId) {
        User userById = userService.getUserById(userId);
        if (ObjectUtil.isNull(userById)) {
            return Result.error(Constants.String_CODE_400, "用户不存在");
        }
        List<UserClientVO> userClientVOS;
        if (userById.getIsAllClient().equals("1")) {
            List<Long> clientIds = userById.getClientIds();
            List<Long> clientIds1 = new ArrayList<>();
            clientIds1.addAll(clientIds);
            while (clientIds1.size() > 0) {
                LambdaQueryWrapper<Client> clientLambdaQueryWrapper = new LambdaQueryWrapper<>();
                clientLambdaQueryWrapper.in(Client::getPcId, clientIds1);
                clientIds1 = clientService.list(clientLambdaQueryWrapper).stream().map(Client::getId).collect(Collectors.toList());
                clientIds.addAll(clientIds1);
            }
            List<Client> clients = clientService.listByIds(clientIds);
            userClientVOS = clients.stream().map(client -> {
                UserClientVO userClientVO = new UserClientVO();
                userClientVO.setValue(client.getId());
                userClientVO.setLabel(client.getName());
                return userClientVO;
            }).collect(Collectors.toList());
        }else {
            userClientVOS = clientService.list().stream().map(client -> {
                UserClientVO userClientVO = new UserClientVO();
                userClientVO.setValue(client.getId());
                userClientVO.setLabel(client.getName());
                return userClientVO;
            }).collect(Collectors.toList());
        }
        return Result.success(userClientVOS);
    }

    /**
     * 新增或者更新
     */
    @PostMapping("/edit")
    @SysLog("新增或者更新用户")
    public Result save(@RequestBody User user) {
        if (ObjectUtil.isEmpty(user.getId())) {
            user.setPassword(SecureUtil.md5("123456"));
            user.setCreateTime(new Date());
            user.setIsDelete(0);
            user.setIsOnline("1");
        } else {
            user.setUpdateTime(new Date());
        }
        if (user.getIsAllClient().equals("1")) {
            List<Long> userClientIds = user.getClientIds();
            List<Long> clientIds = new ArrayList<>();
            clientIds.addAll(userClientIds);
            List<Long> clientIds1 = new ArrayList<>();
            clientIds1.addAll(clientIds);
            while (clientIds1.size() > 0) {
                LambdaQueryWrapper<Client> clientLambdaQueryWrapper = new LambdaQueryWrapper<>();
                clientLambdaQueryWrapper.in(Client::getPcId, clientIds1);
                clientIds1 = clientService.list(clientLambdaQueryWrapper).stream().map(Client::getId).collect(Collectors.toList());
                clientIds.addAll(clientIds1);
            }
            Set<Long> organizationIds = clientService.listByIds(clientIds).stream().map(Client::getOrganization).collect(Collectors.toSet());
            List<Organization> organizations = organizationService.listByIds(organizationIds);
            Long organizationId = 1l;
            if (organizations.size() == 1) {
                user.setOrganization(organizations.get(0).getPid());
            } else {
                for (int i = 0; i < 8; i++) {
                    if (i == 0) {
                        List<Long> list = organizations.stream().map(Organization::getScTeam).collect(Collectors.toList());
                        HashSet<Long> set = new HashSet<>(list);
                        if (list.size() == organizations.size() && set.size() == 1) {
                            organizationId = list.get(0);

                        } else {
                            organizationId = organizations.get(0).getCountry();
                            break;
                        }
                    } else if (i == 1) {
                        List<Long> list = organizations.stream().map(Organization::getFcTeam).collect(Collectors.toList());
                        HashSet<Long> set = new HashSet<>(list);
                        if (list.size() == organizations.size() && set.size() == 1) {
                            organizationId = list.get(0);
                        } else {
                            organizationId = organizations.get(0).getScTeam();
                            break;
                        }
                    } else if (i == 2) {
                        List<Long> list = organizations.stream().map(Organization::getFbTeam).collect(Collectors.toList());
                        HashSet<Long> set = new HashSet<>(list);
                        if (list.size() == organizations.size() && set.size() == 1) {
                            organizationId = list.get(0);
                        } else {
                            organizationId = organizations.get(0).getFcTeam();
                            break;
                        }
                    } else if (i == 3) {
                        List<Long> list = organizations.stream().map(Organization::getCommunity).collect(Collectors.toList());
                        HashSet<Long> set = new HashSet<>(list);
                        if (list.size() == organizations.size() && set.size() == 1) {
                            organizationId = list.get(0);
                        } else {
                            organizationId = organizations.get(0).getFbTeam();
                            break;
                        }
                    } else if (i == 4) {
                        List<Long> list = organizations.stream().map(Organization::getBuilding).collect(Collectors.toList());
                        HashSet<Long> set = new HashSet<>(list);
                        if (list.size() == organizations.size() && set.size() == 1) {
                            organizationId = list.get(0);
                        } else {
                            organizationId = organizations.get(0).getCommunity();
                            break;
                        }
                    } else if (i == 5) {
                        List<Long> list = organizations.stream().map(Organization::getUnit).collect(Collectors.toList());
                        HashSet<Long> set = new HashSet<>(list);
                        if (list.size() == organizations.size() && set.size() == 1) {
                            organizationId = list.get(0);
                        } else {
                            organizationId = organizations.get(0).getBuilding();
                            break;
                        }
                    } else if (i == 6) {
                        List<Long> list = organizations.stream().map(Organization::getFloor).collect(Collectors.toList());
                        HashSet<Long> set = new HashSet<>(list);
                        if (list.size() == organizations.size() && set.size() == 1) {
                            organizationId = list.get(0);
                        } else {
                            organizationId = organizations.get(0).getUnit();
                            break;
                        }
                    } else {
                        List<Long> list = organizations.stream().map(Organization::getRoom).collect(Collectors.toList());
                        HashSet<Long> set = new HashSet<>(list);
                        if (list.size() == organizations.size() && set.size() == 1) {
                            organizationId = list.get(0);
                        } else {
                            organizationId = organizations.get(0).getFloor();
                            break;
                        }
                    }
                }
                user.setOrganization(organizationId);
            }
        } else {
            user.setClientIds(null);
        }
        return Result.success(userService.saveOrUpdate(user));
    }

    /**
     * 删除
     */
    @GetMapping("delete/{id}")
    @SysLog("删除用户")
    public Result delete(@PathVariable Long id) {
        User user = userService.getUserById(id);
        user.setIsDelete(1);
        return Result.success(userService.saveOrUpdate(user));
    }

    /**
     * 查询所有
     */
    @GetMapping("/all")
    public Result findAll() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete", 0);
        List<User> list = userService.list(queryWrapper);
        return Result.success(list);
    }

    /**
     * 根据id查询
     */
    @GetMapping("/{id}")
    public Result findOne(@PathVariable Long id) {
        return Result.success(userService.getUserById(id));
    }

    /**
     * 分页查询
     */
    @GetMapping("/page")
    public Result findPage(@RequestParam Integer pageNum,
                           @RequestParam Integer pageSize,
                           Integer level,
                           Long organizationId,
                           Long userId,
                           String keyWord,
                           Integer role) {
        pageNum = pageNum * pageSize - pageSize;
        List<User> users = userMapper.getUsersByOrganId(pageNum, pageSize, organizationId, userId, keyWord, role, level);
        Long count = userMapper.getUsersCountByOrganId(organizationId, userId, keyWord, role, level);
        HashMap<String, Object> map = new HashMap<>();
        map.put("record", users);
        map.put("total", count);
        return Result.success(map);
    }

    /**
     * 重置用户密码
     */
    @GetMapping("resetPwd")
    @ApiOperation("重置用户密码")
    @SysLog("重置用户密码")
    public Result resetPwd(int id) {
        userService.resetPwd(id, SecureUtil.md5("123456"), new Date());
        return Result.success(true);
    }

    /**
     * 修改密码
     *
     * @param userPasswordDTO
     * @return
     */
    @PostMapping("/password")
    @SysLog("修改用户密码")
    public Result password(@RequestBody UserPasswordDTO userPasswordDTO) {
        userPasswordDTO.setPassword(SecureUtil.md5(userPasswordDTO.getPassword()));
        userPasswordDTO.setNewPass(SecureUtil.md5(userPasswordDTO.getNewPass()));
        userService.updatePassword(userPasswordDTO);
        return Result.success();
    }

    @ApiOperation("导出用户数据")
    @GetMapping("/export")
    public void export(HttpServletResponse response,
                         Integer level,
                         Long organizationId,
                         Long userId,
                         String keyWord,
                         Integer role) {
        userService.export(response, level, organizationId, userId, keyWord, role);
    }

    @ApiOperation("导入用户数据")
    @PostMapping("/importData")
    @SysLog("导入用户数据")
    public void importData(MultipartFile file) {
        userService.importData(file);
    }
}

